﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Soft4science.EquationServer;

using System.Diagnostics;
using System.Text.RegularExpressions;

namespace BtLibs
{
    public static class LatexUtility
    {
        
        //<math display='block' xmlns='http://www.w3.org/1998/Math/MathML'>
        //<math xmlns='http://www.w3.org/1998/Math/MathML'>

        private const string MATHML_BEGIN = "<math ";
        //private const string MATHML_BEGIN = "<math display='block'";
        private const string MATHML_END = "</math>";

        private const string CONST_EMPTY = "";

        private static int mathtypeFormCount = 0;

        public static string WmfBytesToMathML(byte[] bytes)
        {
            byte[] startBuffer = Encoding.UTF8.GetBytes(MATHML_BEGIN);
            byte[] endBuffer = Encoding.UTF8.GetBytes(MATHML_END);
            int startIndex = ByteUtility.IndexOf(bytes, startBuffer);
            int endIndex = ByteUtility.IndexOf(bytes, endBuffer);
            if (startIndex < 0 || endIndex < 0)
            { return ""; }
            endIndex += endBuffer.Length;
            string mathML = Encoding.UTF8.GetString(bytes, startIndex, endIndex - startIndex);
            return mathML;
        }



        public static string MathMLToLatexByMathTypeSDK(String mathML) {
            MathTypeFormResourceManager();
            MathTypeSDKImpl mathTypeSDKImpl = new MathTypeSDKImpl();
            ConvertEquation ce = new ConvertEquation();
            File.WriteAllText("MathML.txt", mathML, Encoding.UTF8);

            int translateCode = ce.Convert(new EquationInputFileText(mathTypeSDKImpl.GetInputFolder("MathML.txt"), ClipboardFormats.cfMML),
                       new EquationOutputFileText(mathTypeSDKImpl.GetOutputFile("Latex.txt"), "Texvc.tdl"));
            if (translateCode < 0)
            {
                throw new FormulasException(translateCode);
            }
            
            string latex = File.ReadAllText("Latex.txt", Encoding.UTF8).Trim();
            latex =  latex.Substring(latex.IndexOf("<math>"),latex.IndexOf("</math>")-latex.IndexOf("<math>")+7);
            return ExFormat(latex);
        }

        private static void MathTypeFormResourceManager()
        {
            if (++mathtypeFormCount > 8)
            {
                MathTypeProcessClose();
                mathtypeFormCount = 0;
            }
        }

        private static void MathTypeProcessClose()
        {
            Process[] ps = Process.GetProcesses();
            foreach (Process item in ps)
            {
                if (item.ProcessName == "MathType")
                {
                    item.Kill();
                    System.Threading.Thread.Sleep(300);
                }
            }
        }

        public static string WmfBytesToLatexByMathTypeSDK(byte[] bytes) {
            string mathML = WmfBytesToMathML(bytes);
            return MathMLToLatexByMathTypeSDK(mathML);
        }

        public static string WmfBytesToLatex(byte[] bytes)
        {
            string mathML = WmfBytesToMathML(bytes);
            Soft4science.EquationServer.winFormsEQServer server = new winFormsEQServer();
            string latex = server.MathM2LaTeX(mathML);
            latex = ExFormat(latex);
            return latex;
        }

        /// <summary>
        /// 
        /// </summary>
        private static string ExFormat(string latex)
        {
            if (latex.StartsWith(@"\[ ") && latex.EndsWith(@" \]"))
            {
                latex = latex.Substring(3, latex.Length - 6);
            }
            if (latex.StartsWith(@"$") && latex.EndsWith(@"$"))
            {
                latex = latex.Substring(1, latex.Length - 2);
            }
            if (latex.StartsWith(@"<math>") && latex.EndsWith(@"</math>"))
            {
                latex = latex.Substring(6, latex.Length - 13);
            }
           
            //潜规则 Soft4science.EquationServer.winFormsEQServer 无法识别underline(平行且相等)
            latex =  latex.Replace(@"underset{ ? }", @"underline");
            latex =  latex.Replace(@"underset{\bar{\ }}",@"underline");
            
            //来解决一下左大括号
            latex = latex.Replace(@"\{\begin{array}", @"\left\{\begin{array}");
            latex = latex.Replace(@"\end{array}", @"\end{array}\right.");
            /*不会写regex
            string matcherStr = @"\{\begin{array}[^<]*\end{array}";
            Console.Write("大括号处理之前"+latex+"\n");
            Regex regex = new Regex(matcherStr, RegexOptions.Compiled);
            MatchCollection matchs = regex.Matches(latex);
            for (int i = matchs.Count - 1; i >= 0; i--)
            {
                Match match = matchs[i];
                if (match.Groups[0].Success)
                {
                    latex = latex.Replace(@"\{\begin{array}",@"\left\{\begin{array}");
                    latex = latex.Replace(@"\end{array}",@"\end{array}\right.");
                }
            }
            */ 
            
            return latex;
            
        }

        public static string WmfFileToLatex(string file)
        {
            if (!File.Exists(file)) { throw new Exception("file not found. " + file); }
            byte[] bytes = File.ReadAllBytes(file);
            string latex;
            try
            {
                latex = WmfBytesToLatexByMathTypeSDK(bytes);
                return latex;
            }
            catch(FormulasException fe){
                //什么时候记日志的时候记录下fe.message吧
                return CONST_EMPTY;
            }
        }
    }
}
